<?php
namespace App\Services;

use App\Models\LogOutPackageModel;
use App\Models\LogPackageContentModel;
use App\Models\LogPackageModel;
use App\Models\PackageContentModel;
use Illuminate\Support\Facades\DB;
use App\Models\StorageManageModel;
use App\Models\PackageModel;
use Illuminate\Support\Facades\Log;

class PackageService {
    //新建套餐
    static public function add($data, $parentId)
    {
        //检查套餐是否存在
        $condition['package_name'] = $data['package_name'];
        $condition['main_id'] = $parentId;

        $check = SELF::checkPackageInfo($condition);
        if(!empty($check)) {
            return $check;
        }

        $insertId = PackageModel::insertGetId([
                                        'package_name' => $data['package_name'],
                                        'main_id' => $parentId,
                                        'created_at' => time()
                                    ]);

        if($insertId > 0) {
            return ['code' => 0, 'msg' => 'success', 'data' => $insertId];
        }
    }

    //修改套餐
    static public function edit($data, $parentId)
    {
        DB::beginTransaction();

        try {
            $condition[] = ['id', '!=', $data['id']];
            $condition['package_name'] = $data['package_name'];
            $condition['main_id'] = $parentId;

            $check = SELF::checkPackageInfo($condition);
            if(!empty($check)) {
                return $check;
            }

            $isUpdate = PackageModel::where('id', $data['id'])->lockForUpdate()->update(['package_name' => $data['package_name']]);

            DB::commit();
            if($isUpdate !== false) {
                return ['code' => 0, 'msg' => 'success', 'data' => ''];
            }
        } catch (\Exception $e) {
            DB::rollBack();
        }
    }

    static private function checkPackageInfo($condition)
    {
        //检查套餐是否存在
        $checkPackageInfo = PackageModel::where('delete_flag', 0)
                                        ->where($condition)
                                        ->first();

        if(!empty($checkPackageInfo)) {
            return ['code' => 1, 'msg' => '套餐`'.$condition['package_name'].'`已存在', 'data' => ''];
        }
    }

    //添加套餐内容
    static public function packageContentAdd($parentId, $data)
    {
        $storageManageInfo = StorageManageModel::select(
                                                'a.*',
                                                'c.id as f_id',
                                                'c.class_name',
                                                'c.class_no',
                                                'b.id as s_id',
                                                'b.class_name as s_class_name',
                                                'b.class_no as s_class_no',
                                            )
                                            ->from('storage_manage as a')
                                            ->leftJoin('materiel_class as b', 'b.id', '=', 'a.materiel_class_id')
                                            ->leftJoin('materiel_class as c', 'c.id', '=', 'b.parent_id')
                                            ->where('a.id', $data['storage_manage_id'])->first();

        $arr['materiel_first_class_id'] = $storageManageInfo['f_id'];
        $arr['materiel_first_class_name'] = $storageManageInfo['class_name'];
        $arr['materiel_first_class_no'] = $storageManageInfo['class_no'];
        $arr['package_id'] = $data['id'];
        $arr['materiel_class_id'] = $storageManageInfo['s_id'];
        $arr['materiel_class_name'] = $storageManageInfo['s_class_name'];
        $arr['materiel_class_no'] = $storageManageInfo['s_class_no'];
        $arr['storage_manage_id'] = $storageManageInfo['id'];
        $arr['type_id'] = $storageManageInfo['type_id'];
        $arr['materiel_name'] = $storageManageInfo['materiel_name'];
        $arr['type_name'] = $storageManageInfo['type_name'];
        $arr['materiel_no'] = $storageManageInfo['materiel_no'];
        $arr['storage_id'] = $storageManageInfo['storage_id'];
        $arr['storage_name'] = $storageManageInfo['storage_name'];
        $arr['storage_address'] = $storageManageInfo['storage_address'];
        $arr['num'] = $data['num'];
        $arr['main_id'] = $parentId;
        $arr['created_at'] = time();
        $arr['shelf_id'] = $storageManageInfo['shelf_id'];
        $arr['location_id'] = $storageManageInfo['location_id'];

        //检查套餐中是否存在相同类型的在库物料
        $checkPackageContent = PackageContentModel::where([
                                                    'package_id' => $data['id'],
                                                    'storage_manage_id' => $storageManageInfo['id'],
                                                    'type_id' => $storageManageInfo['type_id'],
                                                    'storage_id' => $storageManageInfo['storage_id'],
                                                    'delete_flag' => 0
                                                ])->first();

        if(!empty($checkPackageContent)) {
                return ['code' => 1, 'msg' => '套餐内容已存在', 'data' => ''];
        }

        $insertId = PackageContentModel::insertGetId($arr);

        if($insertId > 0) {
            return ['code' => 0, 'msg' => 'success', 'data' => $insertId];
        }
    }

    //指定套餐内容对应的在库信息列表(修改套餐内容用)
    static public function packageStorageList($parentId, $data)
    {
        $packageContentInfo = PackageContentModel::where('id', $data['id'])->first();

        return StorageManageModel::packageStorageList($parentId, $packageContentInfo);
    }

    //修改套餐内容
    static public function packageContentEdit($data, $parentId)
    {
        DB::beginTransaction();

        try {
            $checkPackageContent = PackageContentModel::where([
                                                        'storage_manage_id' => $data['storage_manage_id'],
                                                        'package_id' => $data['package_id'],
                                                    ])
                                                    ->where('id', '!=', $data['id'])
                                                    ->where('delete_flag', 0)
                                                    ->first();

            if(!empty($checkPackageContent)) {
                    return ['code' => 1, 'msg' => '套餐内容已存在', 'data' => ''];
            }

            $isUpdate = PackageContentModel::where('id', $data['id'])->lockForUpdate()->update($data);

            DB::commit();
            if($isUpdate !== false) {
                return ['code' => 0];
            }
        } catch (\Exception $e) {
            DB::rollBack();
        }
    }

    //添加套餐内容-可用库存物料信息
    static public function packageContentSelect($parentId, $data)
    {
        $packageContentInfo = PackageContentModel::where('package_id', $data['id'])
                                                ->where('delete_flag', 0)
                                                ->get()->toArray();

        $keyword = empty($data['keyword'])?'':$data['keyword'];
        $condition = [];
        if(!empty($data['materiel_class_id'])) {
            $condition['a.materiel_class_id'] = $data['materiel_class_id'];
        }

        $storageManageId = [];
        foreach($packageContentInfo as $key => $value) {
            $storageManageId[] = $value['storage_manage_id'];
        }

        $storageManageInfo = StorageManageModel::list($parentId, $keyword, $condition, $data);

        foreach($storageManageInfo as $k => $v) {
            if(in_array($v['id'], $storageManageId)) {
                $storageManageInfo[$k]['content_exist'] = 1;
            }
            else {
                $storageManageInfo[$k]['content_exist'] = 0;
            }
        }

        return $storageManageInfo;
    }

    //套餐内容列表
    static public function contentList($data)
    {
        return PackageContentModel::getContentInfo($data);
    }

    //套餐出库
    static public function packageOut($data)
    {
        $packageInfo = PackageModel::select(
            'id',
            'package_name'
        )
        ->where([
            'id' => $data['id'],
            'main_id' => $data['main_id'],
            'delete_flag' => 0
        ])
        ->with('hasManyContent', function($query) {
            $query->where('delete_flag', 0);
        })
        ->first()->toArray();

        if(empty($packageInfo)) {
            return ['code' => 1, 'msg' => '套餐不存在，请重试', 'data' => ''];
        }

        $storageManageId = [];//套餐内容中库存信息id
        $packageContentStorageInfo = [];//套餐内容中库存内容id及套餐内物料组成数量
        foreach($packageInfo['has_many_content'] as $key => $value) {
            $storageManageId[] = $value['storage_manage_id'];
            $packageContentStorageInfo[$key] = [
                'id' => $value['storage_manage_id'],
                'num' => $value['num'] * $data['num'],
            ];
        }

        $storageManageInfo = StorageManageModel::select(
            'a.id',
            'a.materiel_class_id',
            'a.type_id',
            'a.storage_id',
            'a.materiel_mean_cost',
            'b.class_name as materiel_class_name',
            'b.class_no as materiel_class_name',
            'c.materiel_name',
            'c.type_name',
            'c.materiel_no',
            'd.storage_name',
            'd.storage_address',
            'a.alert_num',
            'a.in_storage_num',
            'a.virtual_storage_num',
            'a.materiel_mean_cost'
        )
            ->from('storage_manage as a')
            ->leftJoin('materiel_class as b', 'b.id', '=', 'a.materiel_class_id')
            ->leftJoin('materiel_type as c', 'c.id', '=', 'a.type_id')
            ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
            ->whereIn('a.id', $storageManageId)->get();

        $totalCost = 0;
        foreach($storageManageInfo as $kk => $val) {
            if($val['delete_flag'] == 1) {
                return [
                    'code' => 1,
                    'msg' => '套餐内物料商品:`'.$val['materiel_name'].'-'.$val['type_name'].'不存在',
                    'data' => ''
                ];
            }

            $totalCost += $val['materiel_mean_cost'];

            foreach($packageContentStorageInfo as $v) {
                if($val['id'] == $v['id']) {
                    if($val['in_storage_num'] < $v['num']) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内物料商品:`'.$val['materiel_name'].'-'.$val['type_name'].'`库存数不足，当前库存:'.$val['in_storage_num'].',需出库数量:'.$v['num'],
                            'data' => ''
                        ];
                    }
                }

                if($val['virtual_storage_num'] > 0) {
                    if($val['id'] == $v['id']) {
                        if($val['virtual_storage_num'] < $v['num']) {
                            return [
                                'code' => 1,
                                'msg' => '套餐内物料商品:`'.$val['materiel_name'].'-'.$val['type_name'].'`虚拟库存数不足',
                                'data' => ''
                            ];
                        }
                    }
                }
            }
        }

        DB::beginTransaction();

        try {
            $packageLog = [
                'package_id' => $packageInfo['id'],
                'package_name' => $packageInfo['package_name'],
                'num' => $data['num'],
                'sell_price' => $totalCost,
                'cost' => $totalCost,
                'user_id' => $data['user_id'],
                'main_id' => $data['main_id'],
                'remark' => empty($data['remark'])?'':$data['remark'],
                'created_at' => time()
            ];
            $id = LogPackageModel::insertGetId($packageLog);

            $packageContentLog = [];
            $LogOutPackageData = [];
            $materielInfo = [];
            foreach($storageManageInfo as $k1 => $v1) {
                foreach($packageContentStorageInfo as $v2) {
                    if($v1['id'] == $v2['id']) {
                        $packageContentLog[$k1]['log_package_id'] = $id;
                        $packageContentLog[$k1]['package_id'] = $packageInfo['id'];
                        $packageContentLog[$k1]['storage_id'] = $v1['storage_id'];
                        $packageContentLog[$k1]['storage_name'] = $v1['storage_name'];
                        $packageContentLog[$k1]['storage_address'] = $v1['storage_address'];
                        $packageContentLog[$k1]['materiel_class_id'] = $v1['materiel_class_id'];
                        $packageContentLog[$k1]['materiel_class_name'] = $v1['materiel_class_name'];
                        $packageContentLog[$k1]['materiel_class_no'] = $v1['materiel_class_no'];
                        $packageContentLog[$k1]['materiel_type_id'] = $v1['type_id'];
                        $packageContentLog[$k1]['out_storage_manage_id'] = $v1['id'];
                        $packageContentLog[$k1]['materiel_name'] = $v1['materiel_name'];
                        $packageContentLog[$k1]['type_name'] = $v1['type_name'];
                        $packageContentLog[$k1]['materiel_no'] = $v1['materiel_no'];
                        $packageContentLog[$k1]['operate_num'] = $v2['num'] * $data['num'];
                        $packageContentLog[$k1]['last_storage_num'] = $v1['in_storage_num'];
                        $packageContentLog[$k1]['next_storage_num'] = $v1['in_storage_num'] - $v2['num'];
                        $packageContentLog[$k1]['user_id'] = $data['user_id'];
                        $packageContentLog[$k1]['main_id'] = $data['main_id'];
                        $packageContentLog[$k1]['created_at'] = time();

                        $materielInfo[] = [
                            'materiel_name' => $v1['materiel_name'],
                            'type_name' => $v1['type_name'],
                            'materiel_no' => $v1['materiel_no'],
                            'in_storage_num' => $v1['in_storage_num'] - $v2['num'],
                            'alert_num' => $v1['alert_num'],
                            'storage_name' => $v1['storage_name'],
                            'storage_id' => $v1['storage_id'],
                            'num' => $v2['num'],
                        ];

                        $LogOutPackageData[$k1]['storage_manage_id'] = $v1['id'];
                        $LogOutPackageData[$k1]['materiel_class_id'] = $v1['materiel_class_id'];
                        $LogOutPackageData[$k1]['materiel_type_id'] = $v1['type_id'];
                        $LogOutPackageData[$k1]['storage_id'] = $v1['storage_id'];
                        $LogOutPackageData[$k1]['mean_cost'] = $v1['materiel_mean_cost'];
                        $LogOutPackageData[$k1]['out_time'] = strtotime(date('Y-m-d'));
                        $LogOutPackageData[$k1]['created_at'] = time();
                        $LogOutPackageData[$k1]['price'] = $v1['materiel_mean_cost'];
                        $logOutPackageData[$key]['all_id_type'] = 3;//单据类型;0:无;1:报损;2:销售;3:套餐;
                        $logOutPackageData[$key]['all_id'] = $packageInfo['id'];//单据id
                        $LogOutPackageData[$k1]['user_id'] = $data['user_id'];
                        $LogOutPackageData[$k1]['main_id'] = $data['main_id'];
                        $LogOutPackageData[$k1]['num'] = $v2['num'];
                    }
                }
            }

            foreach($packageContentStorageInfo as $v3) {
                $storageManageInfo = StorageManageModel::where('id', $v3['id'])->first();

                if($storageManageInfo['virtual_storage_num'] > 0) {
                    StorageManageModel::where('id', $v3['id'])
                        ->update([
                            'in_storage_num' => DB::raw('in_storage_num - '.$v3['num']),
                            'virtual_storage_num' => DB::raw('virtual_storage_num - '.$v3['num'])
                        ]);
                }
                else {
                    StorageManageModel::where('id', $v3['id'])
                        ->update([
                            'in_storage_num' => DB::raw('in_storage_num - '.$v3['num']),
                        ]);
                }
            }

            foreach($materielInfo as $vv) {
                MessageService::sendAlertSms(
                    $vv['materiel_name'],
                    $vv['type_name'],
                    $vv['in_storage_num'],
                    $vv['alert_num'],
                    $data,
                    $vv['storage_id'],
                    $vv['storage_name'],
                    $vv['num']
                );

                MessageService::sendOutSms(
                    $vv['materiel_name'],
                    $vv['type_name'],
                    $vv['in_storage_num'],
                    $vv['storage_name'],
                    $vv['num'],
                    $data,
                    $vv['storage_id'],
                    $vv['alert_num'],
                );

                MessageService::sendShortSms(
                    $vv['materiel_name'],
                    $vv['type_name'],
                    $vv['in_storage_num'],
                    $data,
                    $vv['storage_name'],
                    $v1['storage_id']
                );
            }

//            PackageModel::where('id', $data['id'])->update(['status' => 0]);

            LogPackageContentModel::insert($packageContentLog);
            LogOutPackageModel::insert($LogOutPackageData);
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('套餐出库：'.var_export($data, true));
        }
    }
}
